package com.situ.studentmanagement.controller;

import com.octo.captcha.Captcha;
import com.octo.captcha.engine.CaptchaEngine;
import com.situ.studentmanagement.CapchaHelper;
import com.situ.studentmanagement.Constants;
import com.situ.studentmanagement.Utils;
import com.situ.studentmanagement.dao.AdminMapper;
import com.situ.studentmanagement.dao.StudentMapper;
import com.situ.studentmanagement.model.CheckInfo;
import com.situ.studentmanagement.model.Student;
import org.apache.ibatis.binding.BindingException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * Created by niugao on 6/13/2016.
 */
@Controller //表示这个类是一个Controller，于是当请求路径 / 时，这个Contrller的实例被自动创建
@RequestMapping("/") //这个controller对应到路径 /
public class MainController {

    //这是mybatis的映射接口，因为使用了@Autowired，它指向的实例会被自动创建
    @Autowired
    private AdminMapper mapper;

    @Autowired
    StudentMapper studentMapper;

    //指定这个方法映射到哪个地址，这里没写地址，它会映射到类的地址。
    @RequestMapping(method = RequestMethod.GET)

    public String index(HttpSession session, Model model) {
        //判断是否已经登录
        if(session.getAttribute(Constants.STUDENT_LOGIN_ATTR_ID)!=null){
            return "redirect:student/check";
        }
        if(session.getAttribute(Constants.ADMIN_LOGIN_ATTR_ID)!=null){
            return "redirect:main";
        }

        model.addAttribute("account_html",Constants.getUnloginAccountHtml());
        return "index";
    }

    //指定这个方法映射到哪个地址，这里没写地址，它会映射到类的地址。
    @RequestMapping(method = RequestMethod.POST)
    public String login(HttpSession session,Model model,
                        @RequestParam("name")String name,
                        @RequestParam("password") String password,
                        @RequestParam("role") String role,
                        @RequestParam("captcha") String token) {
        //存放错误提示
        String errMsg = "";
        int loginID = 0;

//        if (name.equals("")) {
//            name = null;
//        }
//        if (password.equals("")) {
//            password = null;
//        }
        //不论是学生还是管理员登录，都需要验证验证码
        Captcha captcha= (Captcha) session.getAttribute("captcha");
        if(!captcha.validateResponse(token)) {
            //验证码错误！
            errMsg = "验证码输的不对呀!";
            model.addAttribute("value_name", name);
            model.addAttribute("value_password", password);
            model.addAttribute("errMsg", errMsg);
            model.addAttribute("account_html", Constants.getUnloginAccountHtml());
            return "index"; //返回前台文件件的名字。
        }

        if (role.equals("员工登录")) {
            //学生登录
            //直接使用这个mapper即可，不用自己去创建了
            try {
                Student s = this.studentMapper.login(name, password);
                //把id保存到session中
                session.setAttribute(Constants.STUDENT_LOGIN_ATTR_ID, s.getId());
                session.setAttribute(Constants.STUDENT_LOGIN_ATTR_NAME,s.getName());

//                Date date=new Date();
//                DateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//                String time=format.format(date);
//                this.studentMapper.setLoginTime(s.getId(),time);

                return "redirect:student/check";
            }catch (Exception e){
                //如果失败的话，我们要：
                // 1 继续显示登录页面
                // 2 需要在输入框中显示提交之前输入的用户名和密码
                // 3 显示错误信息
                errMsg = "用户名或密码不存在";
                //放到model中的数据可以在jsp中直接使用
                model.addAttribute("value_name",name);
                model.addAttribute("value_password",password);
                model.addAttribute("errMsg",errMsg);
                model.addAttribute("account_html", Constants.getUnloginAccountHtml());
                return "index"; //返回前台文件件的名字。
            }
        } else {
            //管理员登录
            //如果提交了注册信息，验证之
            try {
                //直接使用这个mapper即可，不用自己去创建了
                loginID = this.mapper.login(name, password);
                //把id保存到session中
                session.setAttribute(Constants.ADMIN_LOGIN_ATTR_ID, loginID);
                //登录成功，重定向到main.jsp
                return "redirect:main"; //重定向到 /main这个地址，于是导致浏览器自动访问这个地址，于是下面的home()方法被调用。
            }catch (BindingException e){
                errMsg = "用户名或密码不存在";
                model.addAttribute("value_name",name);
                model.addAttribute("value_password",password);
                model.addAttribute("errMsg",errMsg);
                model.addAttribute("account_html", Constants.getUnloginAccountHtml());
                return "index"; //返回前台文件件的名字。
            }
        }
    }
    //向客户端返回验证码图片的路径
    @RequestMapping("/captcha_img")
    public @ResponseBody
    byte[] getCaptchaImgData(HttpSession session) throws IOException {
        //产生验证码图片

        //获取验证码背景图片的路径，这路径放了很多作为背景的图像
        String captcha_backgrounds = session.getServletContext().getRealPath("/WEB-INF/img/captcha");
        CaptchaEngine ce = CapchaHelper.getCaptchaEngine(captcha_backgrounds);
        //需要admin网页中用js定时从服务端获取当前的验证码
        Captcha captcha = ce.getNextCaptcha();
        //为了验证，把captcha对象放到session中，以在客户端提交验证码时进行验证
        session.setAttribute("captcha", captcha);
        //获取验证码图片，这是未压缩的位图
        BufferedImage image = (BufferedImage) captcha.getChallenge();
        ByteArrayOutputStream bao=new ByteArrayOutputStream();
        //应缩成jpg并写到输出流中
        ImageIO.write(image, "jpg", bao);
        return bao.toByteArray();
    }


    //此页面应定时访问，以获取最新的学生考勤信息
    @RequestMapping("/main")
    String home(HttpSession session, Model model) {
        //先检查是否已登录，因为如果用户直在输入这个路径也可以执行此方法，而用户却不需登录
        Integer adminId = (Integer) session.getAttribute(Constants.ADMIN_LOGIN_ATTR_ID);
        if(adminId == null){
            //未登录，跳转到登录页面
            return "redirect:/";
        }

        //已登录
        //把当天的不正常打卡的学生信息都取出来
        //check_log表中，打了卡就有记录，没打卡就没记录
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date now =new Date();
        Calendar calendar=Calendar.getInstance();
//        calendar.setTime(now);
//        //取得当前时间点的小时或分钟数，计算出一共多少秒
//        long hours = calendar.get(Calendar.HOUR);
//        long minutes = calendar.get(Calendar.MINUTE);
//        long totalSecondsOfDay = hours*3600+minutes*60;

        //把时分秒置成0再加上上班时间的秒数，就是今天的上班时间点
        //calendar.set(calendar.get(Calendar.YEAR),calendar.get(Calendar.MONTH),calendar.get(Calendar.DAY_OF_MONTH));
        Date dayBegin = Utils.getDayBeginTime(now);// calendar.getTime();//记下一天开始的时间

        //形成上课时间
        calendar.setTime(dayBegin);
        calendar.add(Calendar.SECOND,Constants.CLASS_BEGIN_TIME);
        Date classBeginTime=calendar.getTime();

        //形成下课时间
        calendar.setTime(dayBegin);
        calendar.add(Calendar.SECOND,Constants.CLASS_OVER_TIME);
        Date classOverTime=calendar.getTime();

        //形成旷课开始时间
        calendar.setTime(dayBegin);
        calendar.add(Calendar.SECOND,Constants.ABSENCE_TIME);
        Date absenceTime=calendar.getTime();

        //形成各时间点的字符串
        String classBeginTimeStr = sdf.format(classBeginTime);
        String classOverTimeStr =sdf.format(classOverTime);
        String absenceTimeStr=sdf.format(absenceTime);
        String nowStr = sdf.format(now);

        //取所有迟到的人（如果当前时间过了上班时间，但未到旷工时间，取所有过了上班时间才打卡的人们）
        //if(now.getTime() > classBeginTime.getTime() && now.getTime() <absenceTime.getTime()){
        //过了上班时间了，且没到旷工时间，取得所有在上班之后到当前时间点之前的所有打卡记录
        List<CheckInfo> latedChecks = studentMapper.getCheckInfosFromTimeToTime(classBeginTimeStr,absenceTimeStr);
        //发给前台（JSP文件）之前，还得把每条的状态搞对了
        setStatusToLated(latedChecks);
        model.addAttribute("latedChecks",latedChecks);
        //}

        //if(now.getTime() > absenceTime.getTime()){
        //取所有旷工的人（如果当前时间过了旷工时间，取所有过了旷工时间才打卡的人）
        List<CheckInfo> absencedChecks = studentMapper.getCheckInfosFromTimeToTime(absenceTimeStr,nowStr);
        model.addAttribute("absencedChecks",absencedChecks);
        //}

        //出取到当前时间为止(从上班之后开始)，所有未打卡的人
        //sql语句中必须
        List<CheckInfo> noChecks = studentMapper.getNoCheckInfosFromTimeToTime(classBeginTimeStr,nowStr);
        model.addAttribute("noChecks",noChecks);

        return "main";
    }

    private void setStatusToLated(List<CheckInfo> latedChecks) {
        for(CheckInfo ci : latedChecks){
            ci.setStatus("迟到了");
        }
    }

    private void setStatusToLabsenced(List<CheckInfo> latedChecks) {
        for(CheckInfo ci : latedChecks){
            ci.setStatus("旷课了");
        }
    }
}
